package main

import "fmt"

// struct作为key的坑
type UserKey struct {
	ID int
}

func main() {
	_demo1()
	println("--------------------")
	_demo2()
	println("--------------------")
	_demo3()
	println("--------------------")
	_demo4()
	println("--------------------")
	//_demo5()
}

func _demo5() {
	// 并发读写panic示例
	m := make(map[int]int)

	// 写goroutine
	go func() {
		for i := 0; ; i++ {
			m[i] = i
		}
	}()

	// 读goroutine
	go func() {
		for i := 0; ; i++ {
			_ = m[i]
		}
	}()

	select {} // 阻塞程序: fatal error: concurrent map read and map write
}

func _demo4() {
	// 错误示例：未初始化赋值
	//var mp map[int]string
	//mp[1] = "test" // panic: assignment to entry in nil map

	// 正确示例：初始化后使用
	var m map[int]string
	m = make(map[int]string) // 初始化
	m[1] = "test"
	fmt.Println(m[1]) // 输出：test

	// 结构体中的map字段容易遗漏初始化
	type Config struct {
		Data map[string]string
	}
	var cfg Config
	cfg.Data = make(map[string]string) // 必须初始化
	cfg.Data["name"] = "Go"
	fmt.Println(cfg.Data) // 输出：map[name:Go]
}

func _demo3() {
	//稍微复杂一点的map初始化
	type Position struct {
		x float64
		y float64
	}
	m2 := map[Position]string{
		Position{29.935523, 52.568915}:  "school",
		Position{25.352594, 113.304361}: "shopping-mall",
		Position{73.224455, 111.804306}: "hospital",
	}
	fmt.Println("m2", m2) //map[{25.352594 113.304361}:shopping-mall {29.935523 52.568915}:school {73.224455 111.804306}:hospital]
}

func _demo2() {
	m := make(map[string]int)
	m["a"] = 0

	// 单返回值：无法区分是key不存在还是值为0
	fmt.Println(m["a"], m["b"]) // 输出：0 0

	// 双返回值：精准判断
	aVal, aExist := m["a"]
	bVal, bExist := m["b"]
	fmt.Println("aVal:", aVal)     // 输出：0
	fmt.Println("aExist:", aExist) // 输出：true
	fmt.Println("bVal:", bVal)     // 输出：0
	fmt.Println("bExist:", bExist) // 输出：false

	//fmt.Printf("a: %d（是否存在：%t）, b: %d（是否存在：%t）\n", aVal, aExist, bVal, bExist)
	// 输出：a: 0（是否存在：true）, b: 0（是否存在：false）
}
func _demo1() {
	m := make(map[UserKey]string)
	key := UserKey{ID: 10}
	m[key] = "张三"
	fmt.Println("m[key]", m[key]) // 输出：张三

	key.ID = 100                  // 修改struct字段
	fmt.Println("m[key]", m[key]) // 输出：""（查询不到）
}
